//	SensorDataReceptor.java --- 

package fr.upmc.dtgui.example.gui;

import java.lang.reflect.InvocationTargetException;
import java.util.Vector;
import java.util.concurrent.BlockingQueue;
import javax.swing.SwingUtilities;

import fr.upmc.dtgui.example.robot.PositioningData;
import fr.upmc.dtgui.example.robot.RobotStateData;

/**
 * The class <code>SensorDataReceptor</code> implements threads used to
 * receive sensor data from the controlled robot through a robot state data
 * blocking queue.  The thread repeatedly looks into the blocking queue for
 * new data, waiting if no data is available, and schedules into the main
 * processing thread of the GUI the updates to the different data that has
 * to be displayed.
 *
 * <p><strong>Invariant</strong></p>
 * 
 * <pre>
 * invariant	true
 * </pre>
 * 
 * <p>Created on : 2011-09-19</p>
 * 
 * @author	<a href="mailto:Jacques.Malenfant@lip6.fr">Jacques Malenfant</a>
 * @version	$Name$ -- $Revision$ -- $Date$
 */
public class SensorDataReceptor extends Thread {

	final protected PositionDisplay					positionDisplay ;
	final protected TeleoperationBoard				tBoard ;
	final protected BlockingQueue<RobotStateData>	dataQueue ;

	public SensorDataReceptor(
		PositionDisplay positionDisplay,
		TeleoperationBoard tBoard,
		BlockingQueue<RobotStateData> dataQueue
		)
	{
		super();
		this.positionDisplay = positionDisplay;
		this.tBoard = tBoard ;
		this.dataQueue = dataQueue;
	}

	@Override
	public void run() {
		RobotStateData rsd = null ;
		Vector<RobotStateData> current = new Vector<RobotStateData>(4) ;
		while (true) {
			try {
				rsd = this.dataQueue.take() ;		// wait if empty...
			} catch (InterruptedException e) {
				e.printStackTrace();
			}
			current.add(rsd) ;
			int n = this.dataQueue.drainTo(current) ;	// do not wait...
			for (int i = 0 ; i <= n ; i++) {
				rsd = current.elementAt(i) ;
				try {
					if (rsd instanceof PositioningData) {
						final PositioningData pd = (PositioningData) rsd ;
						SwingUtilities.invokeAndWait(
							new Runnable() {
								public void run() {
									pd.processData(positionDisplay) ; }
							}) ;
					} else {
						final RobotStateData rsd1 = rsd ;
						SwingUtilities.invokeAndWait(
							new Runnable() {
								public void run() {
									rsd1.processData(tBoard) ; }
							}) ;
					}
				} catch (InterruptedException e) {
					e.printStackTrace();
				} catch (InvocationTargetException e) {
					e.printStackTrace();
				}
			}
			current.clear() ;
		}
	}

}

// $Id$